
#pragma once;

#include "OgreMath/OgreVector3.h"
#include "OgreMath/OgreColourValue.h"
#include "Ray.h"

struct Scene;
class SceneRenderer;

struct Material;
/*typedef std::function<void(Ogre::ColourValue&,
	const Ogre::Vector3&,
	const Ogre::Vector3&,
	const Material&,
	const Scene&,
	const SceneRenderer&,
	int recursionLevel)> MaterialFn;*/

struct FragmentProgramData
{
	Ogre::Vector3 position;
	Ogre::Vector3 normal;
	Ogre::Vector3 userData[1];
};

typedef void (*MaterialFn) (Ogre::ColourValue&,
	const FragmentProgramData&,
	const Material&,
	const Scene&,
	const SceneRenderer&,
	int recursionLevel);

struct Material
{
	Material() {}
	Material(const Ogre::ColourValue &_colour, float _shininess, MaterialFn _fn, float _alpha = 1.0f)
		: colour(_colour), shininess(_shininess), fn(_fn), alpha(_alpha) {}
	Ogre::ColourValue colour;
	float shininess;
	float alpha;

	MaterialFn fn;
};

class Materials
{
public:
	static void white(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);

	static void phong(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);

	static void normals(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);

	static void barycentricCoords(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);

	static void phongReflective(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);

	static void chess(Ogre::ColourValue& outColour, const FragmentProgramData& fragData, const Material &material, const Scene& scene, const SceneRenderer& sceneRenderer, int recursionLevel);
};
